/*
 * Copyright (C) 2010 The Android Open Source Project 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at 
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 */
package com.freeforall;

import android.util.Log;

/**
 * Represents a color piece trying to eat other pieces on the grid.
 * @author Erik Buchholz
 * @author Mike Peterson
 */
public class Piece implements Runnable{

	private boolean eaten;
	private int x;
	private int y;
	private int prevX;
	private int prevY;
	private int xDir;
	private int yDir;
	private int direction;
	private int color;
	private long dt;
	private long prevTime;
	private int spiralPower;
	private int spiralCounter;
	private Object pauseObject;
	
	/** Makes a new Piece of the given color. */
	public Piece(int x, int y, int color, Object pauseObject){
		this.x = x;
		this.y = y;
		this.color = color;
		eaten = false;
		setInitDirectionSpiral();
		prevTime = System.currentTimeMillis();
		spiralCounter = 0;
		spiralPower = 1;
		this.pauseObject = pauseObject;
	}
	
	/** Run the Piece, which moves at set intervals. It stops if eaten. */
	public void run(){
		while(!eaten){
			if (GameParams.getInstance().exiting) return;
			if (GameParams.getInstance().leaving){
				synchronized (pauseObject){
					try{
						pauseObject.wait();
					}
					catch(InterruptedException e){
						// this should not happen
						Log.e("FreeForAll", "Piece Interrupted.");
					}
				}
			}
			if (GameParams.getInstance().isPaused){
				prevTime = System.currentTimeMillis();
				continue;
			}
			dt += System.currentTimeMillis() - prevTime;
			prevTime = System.currentTimeMillis();
			if (dt > GameParams.getInstance().gameSpeed){
				dt -= GameParams.getInstance().gameSpeed;
				setDirectionSpiral();
				move();
			}
		}
	}
	
	/** Move the piece into a new cell. */
	private void move(){
		prevX = x;
		prevY = y;
		x = x + xDir;
		y = y + yDir;
		if (x < 0) x = Game.GRID_SIZE - 1;
		if (y < 0) y = Game.GRID_SIZE - 1;
		x %= Game.GRID_SIZE;
		y %= Game.GRID_SIZE;
		Game.CELL_GRID[y][x].insertPiece(this);
	}
	
	/** Pick a random direction to start moving in. Used Spiral version instead. */
	/*
	private void setInitDirection(){
		xDir = 0;
		switch((int)(Math.random() * 4)){
		case 0:
			direction = 1;
			yDir = -1;
			break;
		case 1:
			direction = 0;
			yDir = -1;
			break;
		case 2:
			direction = 2;
			yDir = 1;
			break;
		case 3:
			direction = 3;
			yDir = 1;
			break;
		}
	}
	*/
	
	private void setInitDirectionSpiral(){
			direction = 0;
			xDir = 0;
			yDir = -1;
	}
	
	
	/** Pick a new direction to move in. Replaced with Spiral algorithm. */
	/*
	private void setDirection(){
		if (direction == 1){
			xDir = (xDir + 1) % 2;
			yDir = -((Math.abs(yDir) + 1) % 2);
		}
		else if (direction == 0){
			xDir = -((Math.abs(xDir) + 1) % 2);
			yDir = -((Math.abs(yDir) + 1) % 2);
		}
		else if (direction == 2){
			xDir = (xDir + 1) % 2;
			yDir = (yDir + 1) % 2;
		}
		else if (direction == 3){
			xDir = -((Math.abs(xDir) + 1) % 2);
			yDir = (yDir + 1) % 2;
		}
	}
	*/
	
	/** Pick a new direction to move in for the spiral pattern. */
	private void setDirectionSpiral(){
		if (spiralCounter < spiralPower){
			spiralCounter++;
		}
		else{
			spiralCounter = 0;
			
			rotateCW();
		}
	}
	
	/** Change the direction to rotate in a clockwise. */
	private void rotateCW(){
		if (direction == 1){
			xDir = 0;
			yDir = 1;
		}
		else if (direction == 0){
			xDir = 1;
			yDir = 0;
			
		}
		else if (direction == 2){
			xDir = -1;
			yDir = 0;
		}
		else if (direction == 3){
			xDir = 0;
			yDir = -1;
			spiralPower++;
		}
		direction = (direction+1)%4;
	}
	
	/** Eat another piece. */
	public void eat(Piece piece){
		piece.eaten = true;
	}
	
	/* Accessors */
	public int getColor(){
		return color;
	}
	
	// Special accessor to get names of colors
	public String getColorName(){
		switch(color){
		case 0xffffff00:
			return "Yellow";
		case 0xffff0000:
			return "Red";
		case 0xff00ff00:
			return "Green";
		case 0xff0000ff:
			return "Blue";
		}
		return "Some Color";
	}
	
	public int getPrevX(){
		return prevX;
	}
	
	public int getPrevY(){
		return prevY;
	}
	
	public boolean getEaten(){
		return eaten;
	}
}
